home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
gfx
/
edit
/
TSMrph23s.lha
/
TSM23s.lha
/
TSMorph-render.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-08
|
90KB
|
2,877 lines
// TSMorph - Amiga Morphing program
// Copyright (C) © 1993 Topicsave Limited
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mpaddock@cix.compulink.co.uk
// $Author: M_J_Paddock $
// $Date: 1993/09/11 21:55:48 $
// $Revision: 1.16 $
/* Amiga headers */
#define INTUI_V36_NAMES_ONLY
#define INTUITION_IOBSOLETE_H
// Include correct math library
#ifdef MY68881
#include <m68881.h>
#else
#include <math.h>
#endif
// prevent inclusion of another math library
#define LIBRARIES_MATHFFP_H
// other headers, define some non 2.02 header stuff
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#ifndef PGA_NewLook
#define PGA_NewLook (PGA_Dummy + 0x000A)
#endif
#include <intuition/imageclass.h>
#include <intuition/icclass.h>
#include <devices/input.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <libraries/gadtools.h>
#ifndef GTMN_FullMenu
#define GTMN_FullMenu GT_TagBase+62
#endif
#include <libraries/asl.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/layers_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/input_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/asl_protos.h>
#include <clib/utility_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/layers_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/input_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/asl_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <proto/diskfont.h>
#include <proto/icon.h>
#include <devices/timer.h>
#include <clib/timer_protos.h>
#include <pragmas/timer_pragmas.h>
#include <clib/alib_protos.h>
#include <rexx/errors.h>
#include <pragmas/rexxsyslib_pragmas.h>
#include <clib/rexxsyslib_protos.h>
#include <libraries/amigaguide.h>
#include <clib/amigaguide_protos.h>
#include <pragmas/amigaguide_pragmas.h>
#include <libraries/reqtools.h>
#include <clib/reqtools_protos.h>
#include <pragmas/reqtools.h>
#include <opal/opallib.h>
#include <libraries/dctv.h>
#include <clib/dctv_protos.h>
#include <pragmas/dctv_pragmas.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Below is not in the 2.02 version of clib/utility_protos.h
pragmas/utility_pragmas.h */
#if INCLUDE_VERSION < 37
LONG Stricmp(UBYTE *string1,UBYTE *string2);
#pragma libcall UtilityBase Stricmp A2 9802
#endif
// IFF header
#include "iffp/ILBMapp.h"
// Progress requester
#include "progress.h"
// JPEG load stuff
#include "JPEG_LS/jinclude.h"
// Help nodes
STRPTR context[] = {
"",
"Main",
"Err-IFFBMHD",
"Err-IFFRaster",
"Err-IFFBODY",
"Err-IFFCLIP",
"Err-IFFILBM",
"Err-IFFFileS",
"Err-IFFTop",
"Err-IFFMemory",
"Req-Progress",
"Err-LibraryR",
"Err-Saving",
"Err-AllocVec",
"Err-OpenPoints",
"Err-Progress",
"Err-AllocPlanes",
"Err-24",
"Err-Load",
"Err-AllocIFF",
"Err-AllocILBM",
"Err-FileFormat",
"Err-SizeMatch",
"Err-Range",
"Err-MemPointsR",
"Err-CloseFile",
"Err-3Points",
"Err-OpenFile",
"Err-ARexx",
"Req-Really_quit",
"Err-OldFormat",
"Err-OpalVision",
"Err-NoOpal",
};
#define H_Help 10
#define H_Library 11
#define H_ESave 12
#define H_AllocVec 13
#define H_OpenPoints 14
#define H_Progress 15
#define H_AllocPlanes 16
#define H_24 17
#define H_Load 18
#define H_AllocIFF 19
#define H_AllocILBM 20
#define H_FileFormat 21
#define H_SizeMatch 22
#define H_Range 23
#define H_MemPointsR 24
#define H_CloseFile 25
#define H_3Points 26
#define H_Open 27
#define H_ARexx 28
#define H_Really 29
#define HE_OldFormat 30
#define HE_OpalVision 31
#define HE_NoOpal 32
// Disable Ctrl-C checking
int CXBRK(void) { return(0); }
int chkabort(void) { return(0); }
// Libraries
extern struct Library *SysBase;
extern struct DOSBase *DOSBase;
struct Library *IntuitionBase, *GfxBase, *LayersBase, *IFFParseBase;
struct Library *GadToolsBase, *AslBase, *UtilityBase;
struct Library *RexxSysBase;
struct Library *AmigaGuideBase;
struct Library *TimerBase=NULL;
struct Library *ReqToolsBase;
struct Library *DCTVBase;
struct OpalBase *OpalBase = NULL;
extern struct List InfoList; // List of messages
// Help stuff
AMIGAGUIDECONTEXT handle;
struct NewAmigaGuide nag = {NULL};
ULONG ASig = 0;
/* Version string for CLI version */
#ifdef MY68881
char *Version = "$VER: TSMorph-render_881 2.3 (6.10.93)";
#else
char *Version = "$VER: TSMorph-render 2.3 (6.10.93)";
#endif
BOOL Pic1_Open = FALSE; // 1st image open OK
BOOL Pic2_Open = FALSE; // 2nd image open OK
struct MsgPort *WMsgPortp; // Message port for Picture Windows
// Properties for IFF read
LONG props[] = { ID_ILBM, ID_BMHD,
ID_ILBM, ID_CAMG,
ID_ILBM, ID_CMAP,
TAG_DONE };
LONG stops[] = { ID_ILBM, ID_BODY,
TAG_DONE };
LONG nowt[] = { TAG_DONE };
/* Wait pointer */
static USHORT __chip BusyPointerData[] =
{
0x0000,0x0000,
0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
0x0000,0x0000,
};
// Protos
BOOL SaveFile(void);
BOOL Load24bit(char *filename,struct Picture *pic,BOOL GUI);
void Close24bit(struct Picture *pic);
void Error(char *ErrorMessage, char *Gadget,char *extra,ULONG hnum);
void DeleteAllPoints(void);
void __regargs FindPoint(struct MyPoint *RetPoint);
BOOL MyOpen(char *filename,BOOL JustPoints);
UWORD __regargs intersect(struct MyPoint *Pointa,struct MyPoint *Pointb);
void __regargs CalcDiffs(struct MyPoint *a,struct MyPoint *bb,double *ab1,double *ab2,double *ab);
void __regargs Triangle(struct MyPoint *p,struct MyPoint *a,struct MyPoint *bb,struct MyPoint *c);
void __regargs checktriangle(struct MyPoint *,struct MyPoint *,struct MyPoint *,struct MyPoint **,struct MyPoint **,struct MyPoint **,ULONG *,UWORD *);
LONG SendRxMsg(char *msgtxt,BOOL IgnoreError);
extern void MyArgArrayInit(int argc,char **argv);
extern void MyArgArrayDone(void);
extern UBYTE *MyArgString(UBYTE *arg2,UBYTE *arg3,BOOL reopen);
extern LONG MyArgInt(UBYTE *arg2, long arg3,BOOL reopen);
extern BOOL MyFindToolType(UBYTE *arg2,BOOL reopen);
void OpenNewArgs(UBYTE *filename);
void DisableWindow(void);
void EnableWindow(void);
void help(ULONG hnum);
BOOL LoadFrames(BOOL points,BOOL image1,BOOL image2);
void AddMessage(UBYTE *message);
// Args.c
void argArrayDone( void );
char **argArrayInit( LONG argc, char **argv );
// SaveHAMetc.c
BOOL SaveBW16(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveBW256(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveHAM6(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveHAM8(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
BOOL SaveDCTV(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
USHORT pwidth, USHORT pheight, USHORT pmode,
UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
// some work buffers
char buffer[256]="";
char buffer1[512]="";
// Image structure
struct Picture {
struct ILBMInfo *ilbm; // For IFF read
UBYTE *red; // Read chunky pixels Must be RGB for Opal OVtoRGB
UBYTE *green; // Green
UBYTE *blue; // Blue
UBYTE filename[256]; // filename
struct OpalScreen *OScrn; // OpalScreen
BOOL rgbonelot; // Is red,green,blue one AllocVec
};
struct Picture Pic1={0},Pic2={0};// 1st and 2nd image
UBYTE *plane0=NULL; // Planes for temporary bit maps
UBYTE *plane1=NULL;
UBYTE *plane2=NULL;
UBYTE *plane3=NULL;
UBYTE *plane4=NULL;
UBYTE *plane5=NULL;
UBYTE *plane6=NULL;
UBYTE *plane7=NULL;
// Point structure
struct MyPoint {
struct MinNode MyNode; // linked into list
WORD x,y; // Coordinates in 1st image
WORD x1,y1; // 2nd image
WORD Cx,Cy; // Current image
LONG Cdiff; // seperation between two points (squared)
WORD xdiff; // x difference
WORD ydiff; // y difference
double xd,yd; // double coords for AntiAlias
double x1d,y1d;// 2nd image
};
// 24 bitplane bitmap
struct MyBitMap {
struct BitMap BitMap;
PLANEPTR xplanes[16];
};
// List of points
struct List PointList;
// Size of image
USHORT width, height, pwidth, pheight, pmode;
char AnimName[256]; // Buffer for file name to save
char *Loadscript; // ARexx load script
WORD x,y; // Current coords
struct MyPoint **Points = NULL; // Pointer to points
UWORD Depth; // Number of points to check each time
UWORD Mode; // Mode = 0 use 3 closest if no others, choose 1st 3
// Mode = 1 leave points stationary, choose 1st 3
// Mode = 2 choose 3 closet, always use
// Mode = 3 leave points stationary, choose 3 closest
#define MODE_STAT 1
#define MODE_CLOSEST 2
LONG PointCount = 0; // Number of points
struct MyPoint BigPoint; // Point far away
char MyFileName[257];
// Settings stuff
char **ArgArray;
char **ArgArraySettings;
// OpalVision screen
struct OpalScreen *OScrn = NULL;
char *OVFormat; // Format of OpalVision save JPG or IFF (or anything) default
BOOL AntiAlias; // AntiAlias points
// Table of parameters
struct {
LONG xf; // Current frame
LONG xFrames; // Number of frames
LONG xSingle; // Warp or Morph
LONG xmove; // Movement 1 to 2
LONG xr; // red of image 1
LONG xg; // green
LONG xb; // blue
LONG xr2; // red of image 2
LONG xg2; // green
LONG xb2; // blue
LONG xDo; // Produce this image
LONG xrplus; // Add red
LONG xgplus; // green
LONG xbplus; // blue
LONG xrminus; // subtract red
LONG xgminus; // subtract green
LONG xbminus; // subtract blue
LONG xDX; // X skip
LONG xDY; // Y skip
LONG xStart; // Start Frame number
LONG FILLER[32]; // Filler for future expansion
} Arexx;
#define f Arexx.xf
#define Frames Arexx.xFrames
#define Single Arexx.xSingle
#define move Arexx.xmove
#define r Arexx.xr
#define g Arexx.xg
#define b Arexx.xb
#define r2 Arexx.xr2
#define g2 Arexx.xg2
#define b2 Arexx.xb2
#define Do Arexx.xDo
#define rplus Arexx.xrplus
#define gplus Arexx.xgplus
#define bplus Arexx.xbplus
#define rminus Arexx.xrminus
#define gminus Arexx.xgminus
#define bminus Arexx.xbminus
#define DX Arexx.xDX
#define DY Arexx.xDY
#define Start Arexx.xStart
// Display help if available
void
help(ULONG hnum) {
if (handle) {
SetAmigaGuideContext(handle,hnum,NULL);
SendAmigaGuideContext(handle,NULL);
}
}
char FileName[256]; // File name buffer
long OVQuality; // OpalVision JPG quality
BOOL OVFast; // OpalVision fast format IFF
BOOL OVThumb; // OpalVision Thumbail
BOOL HAM6;
BOOL HAM8;
BOOL BW16;
BOOL BW256;
BOOL DCTV3 = FALSE;
BOOL DCTV4 = FALSE;
UBYTE *arrayr, // Pointers to red,green and blue
*arrayg,
*arrayb;
BOOL PPM; // PPM save ?
UBYTE *p[3] = {NULL,NULL,NULL};// chunky pointers - order for OpalVision
#define RED p[0]
#define BLUE p[2]
#define GREEN p[1]
UWORD swidth; // scaled width (in full words)
struct RastPort RP, // Work Rast Ports
TRP;
struct MyBitMap MyBitMap; // Real bit map
PLANEPTR Planes[24] = {NULL}; // Bit planes
BOOL CreateIcons;// Create Icons on pictures?
char *Postscript;// ARexx postscript
/* Main program */
void
main(int argc,char **argv) {
BOOL OkFlag = TRUE; // Is it working ?
char *e = NULL; // error message
struct MyPoint MyPoint; // Points to work with
struct MyPoint *MyPointp;
BOOL Opened; // has file been opened
struct WBStartup *argmsg; // Workbench stuff
struct WBArg *wb_arg;
char *e1; // The rest of the error message
struct Window *oldWindowPtr; // Redirect the system requesters
struct Process *process;
char *filename; // file name
ULONG offset, // 2d to 1d array offsets
offset1;
char *Prescript; // Rexx script names
UWORD myx, // indexes for skipping
myy;
UBYTE xr, // more skipping stuff
xg,
xb;
struct AmigaGuideMsg *agm; // help stuff
struct timeval time1, // To display time per image
time2;
struct timerequest tr;
BOOL t2 = FALSE; // Set when the times calculated
char tbuffer[30];// buffer for time message
ULONG hnum = 0; // Help number for error
BOOL Alloced=FALSE; // Allocated memory?
char *Tstr; // Temp string for parameter
UWORD xbig;
double xsmall; // Int and rest of coords
UWORD ybig;
double ysmall; // y coords
WORD right,down; // move right and down?
UWORD xbig1;
double xsmall1; // Int and rest of coords
UWORD ybig1;
double ysmall1; // y coords
WORD right1,down1;// move right and down?
double a,bb,c,d,a1,b1,c1,d1; // AntiAlias stuff
// Set up BigPoint
BigPoint.Cdiff = 0x7FFFFFFF;
// Initialise points list
NewList(&PointList);
// Try and open reqtools.library and dctv.library
ReqToolsBase = OpenLibrary("reqtools.library",38);
DCTVBase = OpenLibrary("dctv.library",3);
// Set up amigaguide (if available)
if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 33L)) {
nag.nag_BaseName = "TSMorph";
nag.nag_Name = "TSMorph.guide";
nag.nag_ClientPort = "TSMorph-render_HELP";
nag.nag_Context = context;
if (handle = OpenAmigaGuideAsync (&nag, NULL)) {
ASig = AmigaGuideSignal(handle);
}
}
// Try and open the timer
if (!OpenDevice(TIMERNAME,UNIT_MICROHZ,(struct IORequest *) &tr, 0L)) {
TimerBase = (struct Library *)tr.tr_node.io_Device;
}
// Try and open OpalVision library
OpalBase = (struct OpalBase *)OpenLibrary("opal.library",0L);
// Open all the libraries
if (IntuitionBase = OpenLibrary("intuition.library",37L)) {
if (RexxSysBase = OpenLibrary("rexxsyslib.library",0)) {
if (IFFParseBase = OpenLibrary("iffparse.library",37L)) {
if (GfxBase = OpenLibrary("graphics.library",37L)) {
if (LayersBase = OpenLibrary("layers.library",37L)) {
if (GadToolsBase = OpenLibrary("gadtools.library",37L)) {
if (AslBase = OpenLibrary("asl.library",37L)) {
if (UtilityBase = OpenLibrary("utility.library",37)) {
if (IconBase = OpenLibrary("icon.library",37L)) {
if (DiskfontBase = OpenLibrary("diskfont.library",36)) {
// Read and process the parameters
MyArgArrayInit(argc,argv);
PubScreenName = MyArgString("PUBSCREENR",NULL,FALSE);
// Open the progress window
if ((!SetupScreen()) && (!OpenProgressWindow())) {
// redirect requesters
process = (struct Process *)FindTask(NULL);
oldWindowPtr = process->pr_WindowPtr;
process->pr_WindowPtr = ProgressWnd;
// Open the project file (CLI or WB)
DisableWindow();
AddMessage("Opening points file");
if (argc) {
if (filename = ArgString(ArgArray,"FILES",NULL)) {
Opened = MyOpen(filename,FALSE);
}
else {
Opened = MyOpen(NULL,FALSE);
}
}
else {
argmsg = (struct WBStartup *)argv;
if (argmsg->sm_NumArgs > 1) {
wb_arg = argmsg->sm_ArgList;
wb_arg++;
if (wb_arg->wa_Lock) {
NameFromLock(wb_arg->wa_Lock,buffer,256);
}
if (AddPart(buffer,wb_arg->wa_Name,256)) {
Opened = MyOpen(buffer,FALSE);
}
}
else {
Opened = MyOpen(NULL,FALSE);
}
}
if (Opened) {
// Get a few parameters
Tstr = MyArgString("SAVEFORMAT","ILBM24",FALSE);
if (OpalBase) {
if (MatchToolValue(Tstr,"OPAL24") || MatchToolValue(Tstr,"OPAL24T") ||
MatchToolValue(Tstr,"OPAL24F") || MatchToolValue(Tstr,"OPAL24FT")) {
OVFormat = "IFF";
}
else {
if (MatchToolValue(Tstr,"JPEG") || MatchToolValue(Tstr,"JPEGT")) {
OVFormat = "JPG";
}
else {
OVFormat = NULL;
}
}
}
else {
OVFormat = NULL;
}
PPM = MatchToolValue(Tstr,"PPM");
HAM6 = MatchToolValue(Tstr,"HAM6");
HAM8 = MatchToolValue(Tstr,"HAM8");
BW16 = MatchToolValue(Tstr,"BW16");
BW256 = MatchToolValue(Tstr,"BW256");
if (DCTVBase) {
DCTV3 = MatchToolValue(Tstr,"DCTV3");
DCTV4 = MatchToolValue(Tstr,"DCTV4");
}
OVQuality = MyArgInt("QUALITY",75,FALSE);
if (MatchToolValue(Tstr,"OPAL24T") || MatchToolValue(Tstr,"JPEGT")) {
OVThumb = TRUE;
}
else {
OVThumb = FALSE;
}
if (MatchToolValue(Tstr,"OPAL24F") || MatchToolValue(Tstr,"OPAL24FT")) {
OVFast = TRUE;
}
else {
OVFast = FALSE;
}
Prescript = MyArgString("PRESCRIPT","Rexx/Prescript",FALSE);
Postscript = MyArgString("POSTSCRIPT","Rexx/Postscript",FALSE);
Loadscript = MyArgString("LOADSCRIPT","Rexx/Loadscript",FALSE);
DX = MyArgInt("DX",0,FALSE);
DY = MyArgInt("DY",0,FALSE);
Depth = max(MyArgInt("DEPTH",2,FALSE),20);
Mode = MyArgInt("MODE",0,FALSE);
CreateIcons = MatchToolValue(MyArgString("CREATEICONSR","NO",FALSE),"YES");
AntiAlias = MatchToolValue(MyArgString("ANTIALIAS","NO",FALSE),"YES");
// File has been opened, cache width in full words
swidth = (((width+15)>>4)<<4);
AddMessage("Allocating work memory");
// Allocate chunky and ILBM bit maps
if ((RED = AllocVec((swidth*height),0)) &&
(GREEN = AllocVec((swidth*height),0)) &&
(BLUE = AllocVec((swidth*height),0)) &&
((OpalBase && OVFormat && !PPM && (OScrn = CreateScreen24(0,width,height))) ||
PPM ||
(!OVFormat && !PPM &&
(Planes[0] = AllocRaster(width,height)) &&
(Planes[1] = AllocRaster(width,height)) &&
(Planes[2] = AllocRaster(width,height)) &&
(DCTV3 ||
((Planes[3] = AllocRaster(width,height)) &&
(DCTV4 || BW16 ||
((Planes[4] = AllocRaster(width,height)) &&
(Planes[5] = AllocRaster(width,height)) &&
(HAM6 ||
((Planes[6] = AllocRaster(width,height)) &&
(Planes[7] = AllocRaster(width,height)) &&
(HAM8 || BW256 ||
((Planes[8] = AllocRaster(width,height)) &&
(Planes[9] = AllocRaster(width,height)) &&
(Planes[10] = AllocRaster(width,height)) &&
(Planes[11] = AllocRaster(width,height)) &&
(Planes[12] = AllocRaster(width,height)) &&
(Planes[13] = AllocRaster(width,height)) &&
(Planes[14] = AllocRaster(width,height)) &&
(Planes[15] = AllocRaster(width,height)) &&
(Planes[16] = AllocRaster(width,height)) &&
(Planes[17] = AllocRaster(width,height)) &&
(Planes[18] = AllocRaster(width,height)) &&
(Planes[19] = AllocRaster(width,height)) &&
(Planes[20] = AllocRaster(width,height)) &&
(Planes[21] = AllocRaster(width,height)) &&
(Planes[22] = AllocRaster(width,height)) &&
(Planes[23] = AllocRaster(width,height))))))))))))) { // Looks like LISP!!!!
Alloced = TRUE;
// Update the progress
EnableWindow();
GT_SetGadgetAttrs(ProgressGadgets[GDX_Frame],ProgressWnd,NULL,
GTSL_Min,1,
GTSL_Max,Frames,TAG_END);
GT_SetGadgetAttrs(ProgressGadgets[GDX_Line],ProgressWnd,NULL,
GTSL_Min,0,
GTSL_Max,height-1,TAG_END);
// Pass to ARexx for processing
if (strcmp(Prescript,"OFF")) {
AddMessage("Prescript for frame 0");
f = 0;
Do = 0;
strcpy(buffer,Prescript);
strcat(buffer," %ld");
sprintf(buffer1,buffer,&Arexx);
OkFlag = !SendRxMsg(buffer1,FALSE);
if (!OkFlag) {
e = (char *)-1;
}
if (Do && OkFlag) {
OkFlag = LoadFrames(FALSE,TRUE,FALSE);
if (!OkFlag) {
e = (char *)-1;
}
else {
AddMessage("Saving frame 0");
memcpy(RED,Pic1.red,swidth*height);
memcpy(GREEN,Pic1.green,swidth*height);
memcpy(BLUE,Pic1.blue,swidth*height);
OkFlag = SaveFile();
if (!OkFlag) {
e = (char *)-1;
}
}
}
}
// Determine start time
if (TimerBase) {
GetSysTime(&time1);
}
// Loop thru frames
for (f=1;
(f < (Frames+1)) && OkFlag; // no of Frames
f++) {
// Update progress
AddMessage("Prescript processing");
GT_SetGadgetAttrs(ProgressGadgets[GDX_Frame],ProgressWnd,NULL,
GTSL_Level,f,TAG_END);
// calculate default image parameters
rplus = gplus = bplus = rminus = gminus = bminus = 0;
if ((Single == 1) || (Single == 3)) {
move = ((Frames-f) << 10)/Frames;
r = g = b = 1024;
r2 = g2 = b2 = 0;
Do = 1;
}
else {
r = g = b = move = ((Frames-f+1) << 10)/(Frames + 1);
r2 = g2 = b2 = (1024 - r);
Do = 1;
}
// Pass to ARexx for processing
if (strcmp(Prescript,"OFF")) {
strcpy(buffer,Prescript);
strcat(buffer," %ld");
sprintf(buffer1,buffer,&Arexx);
OkFlag = !SendRxMsg(buffer1,FALSE);
if (!OkFlag) {
e = (char *)-1;
}
}
if (OkFlag && Do && ((!Pic1_Open) || (Single == 2) || (Single == 3))) {
if (Pic2_Open) {
Close24bit(&Pic2);
Pic2_Open = FALSE;
}
if (Pic1_Open) {
Close24bit(&Pic1);
Pic1_Open = FALSE;
}
OkFlag = LoadFrames(TRUE,TRUE,TRUE);
if (!OkFlag) {
e = (char *)-1;
}
}
if ((PointCount < 3) && OkFlag) {
Error("Must have at least 3 points","Quit",NULL,H_3Points);
OkFlag = FALSE;
}
if (Do && OkFlag) {
// If we have calculated time per image the display it, update other gadgets
if (t2) {
sprintf(tbuffer,"%ld Seconds for last image",time2.tv_secs);
AddMessage(tbuffer);
}
else {
AddMessage("Rendering image");
}
if (TimerBase) {
GetSysTime(&time1);
}
// We want to do this image so calculate coordinates in this image
if ((Single == 1) || (Single == 3)) {
for (MyPointp = (struct MyPoint *)PointList.lh_Head;
MyPointp->MyNode.mln_Succ;
MyPointp = (struct MyPoint *)MyPointp->MyNode.mln_Succ) {
MyPointp->Cx = (MyPointp->x1*(1024-move)+MyPointp->x*move)>>10;
MyPointp->Cy = (MyPointp->y1*(1024-move)+MyPointp->y*move)>>10;
}
}
else {
for (MyPointp = (struct MyPoint *)PointList.lh_Head;
MyPointp->MyNode.mln_Succ;
MyPointp = (struct MyPoint *)MyPointp->MyNode.mln_Succ) {
MyPointp->Cx = (MyPointp->x1*(1024-move)+MyPointp->x*move)>>10;
MyPointp->Cy = (MyPointp->y1*(1024-move)+MyPointp->y*move)>>10;
}
}
// Initialise chunky pointers
arrayr=RED;
arrayg=GREEN;
arrayb=BLUE;
// loop thru lines
for (y=0;
(y<height) && OkFlag;
y++) {
// Update progress
GT_SetGadgetAttrs(ProgressGadgets[GDX_Line],ProgressWnd,NULL,
GTSL_Level,(ULONG)y,TAG_END);
// Loop thru columns
for (x=0;
x < width;
x++) {
// Determine coordinates on end image(s)
FindPoint(&MyPoint);
if (AntiAlias) {
// Horrible AntiAlias stuff
xbig = floor(MyPoint.xd + 0.5);
xsmall = MyPoint.xd - (double)xbig;
if (xsmall > 0) {
right = 1;
}
else {
xsmall = -xsmall;
right = -1;
}
ybig = floor(MyPoint.yd + 0.5);
ysmall = MyPoint.yd - (double)ybig;
if (ysmall > 0) {
down = swidth;
}
else {
ysmall = -ysmall;
down = -swidth;
}
offset = ybig*swidth+xbig;
a = 1.0 + (xsmall * ysmall) - xsmall - ysmall;
bb = xsmall * (1.0 - ysmall);
c = ysmall * (1.0 - xsmall);
d = xsmall * ysmall;
if ((Single != 1) && (Single != 3)) {
xbig1 = floor(MyPoint.x1d + 0.5);
xsmall1 = MyPoint.x1d - (double)xbig1;
if (xsmall1 > 0) {
right1 = 1;
}
else {
xsmall1 = -xsmall1;
right1 = -1;
}
ybig1 = floor(MyPoint.y1d + 0.5);
ysmall1 = MyPoint.y1d - (double)ybig1;
if (ysmall1 > 0) {
down1 = swidth;
}
else {
ysmall1 = -ysmall1;
down1 = -swidth;
}
offset1 = ybig1*swidth+xbig1;
a1 = 1.0 + (xsmall1 * ysmall1) - xsmall1 - ysmall1;
b1 = xsmall1 * (1.0 - ysmall1);
c1 = ysmall1 * (1.0 - xsmall1);
d1 = xsmall1 * ysmall1;
(*arrayr) = min(max((((ULONG)
((((double) Pic1.red[offset])*a + ((double) Pic1.red[offset+right])*bb+
((double) Pic1.red[offset+down])*c+((double) Pic1.red[offset+down+right])*d)*((double)r) +
(((double) Pic2.red[offset1])*a1 + ((double) Pic2.red[offset1+right1])*b1+
((double) Pic2.red[offset1+down1])*c1+((double) Pic2.red[offset1+down1+right1])*d1)*((double)r2))
)>>10) + rplus - rminus,0),255);
(*arrayg) = min(max((((ULONG)
((((double)Pic1.green[offset])*a + ((double)Pic1.green[offset+right])*bb+
((double)Pic1.green[offset+down])*c+((double)Pic1.green[offset+down+right])*d)*((double)g) +
(((double)Pic2.green[offset1])*a1 + ((double)Pic2.green[offset1+right1])*b1+
((double)Pic2.green[offset1+down1])*c1+((double)Pic2.green[offset1+down1+right1])*d1)*((double)g2))
)>>10) + gplus - gminus,0),255);
(*arrayb) = min(max((((ULONG)
((((double) Pic1.blue[offset])*a + ((double) Pic1.blue[offset+right])*bb+
((double) Pic1.blue[offset+down])*c+((double) Pic1.blue[offset+down+right])*d)*((double)b) +
(((double) Pic2.blue[offset1])*a1 + ((double) Pic2.blue[offset1+right1])*b1+
((double) Pic2.blue[offset1+down1])*c1+((double) Pic2.blue[offset1+down1+right1])*d1)*((double)b2))
)>>10) + bplus - bminus,0),255);
}
else {
(*arrayr) = min(max(((ULONG)
(((((double)Pic1.red[offset])*a + ((double)Pic1.red[offset+right])*bb+
((double)Pic1.red[offset+down])*c+((double)Pic1.red[offset+down+right])*d)
)*((double)r))>>10) + rplus - rminus,0),255);
(*arrayg) = min(max(((ULONG)
(((((double)Pic1.green[offset])*a + ((double)Pic1.green[offset+1])*bb+
((double)Pic1.green[offset+down])*c+((double)Pic1.green[offset+down+right])*d)
)*((double)g))>>10) + gplus - gminus,0),255);
(*arrayb) = min(max(((ULONG)
(((((double)Pic1.blue[offset])*a + ((double)Pic1.blue[offset+1])*bb+
((double)Pic1.blue[offset+down])*c+((double)Pic1.blue[offset+down+right])*d)
)*((double)b))>>10) + bplus - bminus,0),255);
}
}
else {
// Calculate new colours (without AntiAlias)
offset = MyPoint.y*swidth+MyPoint.x;
if ((Single == 1) || (Single == 3)) {
(*arrayr) = min(max(((Pic1.red[offset]*r)>>10) + rplus - rminus,0),255);
(*arrayg) = min(max(((Pic1.green[offset]*g)>>10) + gplus - gminus,0),255);
(*arrayb) = min(max(((Pic1.blue[offset]*b)>>10) + bplus - bminus,0),255);
}
else {
offset1 = MyPoint.y1*swidth+MyPoint.x1;
(*arrayr) = min(max((((Pic2.red[offset1]*r2) +
(Pic1.red[offset]*r))>>10) + rplus - rminus,0),255);
(*arrayg) = min(max((((Pic2.green[offset1]*g2) +
(Pic1.green[offset]*g))>>10) + gplus - gminus,0),255);
(*arrayb) = min(max((((Pic2.blue[offset1]*b2) +
(Pic1.blue[offset]*b))>>10) + bplus - bminus,0),255);
}
}
// If we are skipping columns then copy colour forward
if (DX) {
xr = *arrayr;
xg = *arrayg;
xb = *arrayb;
x++;
for (myx = 0;
(myx < DX) && (x < width);
x++,myx++) {
arrayr++;
*arrayr = xr;
arrayg++;
*arrayg = xg;
arrayb++;
*arrayb = xb;
}
x--;
}
// next column (if not already there)
if (x < width) {
arrayr++;
arrayg++;
arrayb++;
}
}
// end of line, check 'Stop' and 'Help'
OkFlag = HandleProgressIDCMP();
if (handle) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
// skip part word at end of line
arrayr += (swidth - width);
arrayg += (swidth - width);
arrayb += (swidth - width);
// if skipping lines then copy previous line
if (DY) {
y++;
for (myy = 0;
(myy < DY) && (y<height);
y++, myy++) {
memcpy(arrayr, arrayr - swidth, swidth);
arrayr += swidth;
memcpy(arrayg, arrayg - swidth, swidth);
arrayg += swidth;
memcpy(arrayb, arrayb - swidth, swidth);
arrayb += swidth;
}
y--;
}
}
// not ok - already displayed an error
if (!OkFlag) {
e = (char *)-1;
}
else {
// Save image
OkFlag = SaveFile();
// Caclulate time (if we have not already)
if (TimerBase) {
GetSysTime(&time2);
t2 = TRUE;
SubTime(&time2,&time1);
}
// Not ok - already displayed error message
if (!OkFlag) {
e = (char *)-1;
}
}
}
}
if (OkFlag && ((Single == 0) || (Single == 2))) {
// Pass to ARexx for processing
if (strcmp(Prescript,"OFF")) {
AddMessage("Prescript for last frame");
f = Frames+1;
Do = 0;
strcpy(buffer,Prescript);
strcat(buffer," %ld");
sprintf(buffer1,buffer,&Arexx);
OkFlag = !SendRxMsg(buffer1,FALSE);
if (!OkFlag) {
e = (char *)-1;
}
if (OkFlag && Do && ((!Pic1_Open) || (Single == 2))) {
if (Pic2_Open) {
Close24bit(&Pic2);
Pic2_Open = FALSE;
}
if (Pic1_Open) {
Close24bit(&Pic1);
Pic1_Open = FALSE;
}
OkFlag = LoadFrames(FALSE,FALSE,TRUE);
if (!OkFlag) {
e = (char *)-1;
}
}
if (OkFlag && Do) {
AddMessage("Saving last frame");
memcpy(RED,Pic2.red,swidth*height);
memcpy(GREEN,Pic2.green,swidth*height);
memcpy(BLUE,Pic2.blue,swidth*height);
OkFlag = SaveFile();
if (!OkFlag) {
e = (char *)-1;
}
}
}
}
}
AddMessage("Cleaning up");
DeleteAllPoints();
if (RED) FreeVec(RED);
if (GREEN) FreeVec(GREEN);
if (BLUE) FreeVec(BLUE);
if (OScrn) {
FreeScreen24(OScrn);
}
else { // Should not need this if else
if (!PPM) {
if (Planes[0]) FreeRaster(Planes[0],width,height);
if (Planes[1]) FreeRaster(Planes[1],width,height);
if (Planes[2]) FreeRaster(Planes[2],width,height);
if (!DCTV3) {
if (Planes[3]) FreeRaster(Planes[3],width,height);
if (!BW16 && !DCTV4) {
if (Planes[4]) FreeRaster(Planes[4],width,height);
if (Planes[5]) FreeRaster(Planes[5],width,height);
if (!HAM6) {
if (Planes[6]) FreeRaster(Planes[6],width,height);
if (Planes[7]) FreeRaster(Planes[7],width,height);
if (!HAM8 && !BW256) {
if (Planes[8]) FreeRaster(Planes[8],width,height);
if (Planes[9]) FreeRaster(Planes[9],width,height);
if (Planes[10]) FreeRaster(Planes[10],width,height);
if (Planes[11]) FreeRaster(Planes[11],width,height);
if (Planes[12]) FreeRaster(Planes[12],width,height);
if (Planes[13]) FreeRaster(Planes[13],width,height);
if (Planes[14]) FreeRaster(Planes[14],width,height);
if (Planes[15]) FreeRaster(Planes[15],width,height);
if (Planes[16]) FreeRaster(Planes[16],width,height);
if (Planes[17]) FreeRaster(Planes[17],width,height);
if (Planes[18]) FreeRaster(Planes[18],width,height);
if (Planes[19]) FreeRaster(Planes[19],width,height);
if (Planes[20]) FreeRaster(Planes[20],width,height);
if (Planes[21]) FreeRaster(Planes[21],width,height);
if (Planes[22]) FreeRaster(Planes[22],width,height);
if (Planes[23]) FreeRaster(Planes[23],width,height);
}
}
}
}
}
}
if (!Alloced && !e) {
e = "Error AllocVec for output";
e1 = NULL;
hnum = H_AllocVec;
}
}
else {
e = (char *)-1;
}
if (OkFlag) {
e = (char *)-1;
}
if (!e) {
e = "Error Opening points file";
e1 = NULL;
hnum = H_OpenPoints;
}
if (Pic2_Open) {
Close24bit(&Pic2);
Pic2_Open = FALSE;
}
if (Pic1_Open) {
Close24bit(&Pic1);
Pic1_Open = FALSE;
}
if (plane0) FreeVec(plane0);
if (plane1) FreeVec(plane1);
if (plane2) FreeVec(plane2);
if (plane3) FreeVec(plane3);
if (plane4) FreeVec(plane4);
if (plane5) FreeVec(plane5);
if (plane6) FreeVec(plane6);
if (plane7) FreeVec(plane7);
// reset requesters
process->pr_WindowPtr = oldWindowPtr;
}
else {
e = "Error opening progress window";
e1 = NULL;
hnum = H_Progress;
}
// close down everything
CloseProgressWindow();
CloseDownScreen();
MyArgArrayDone();
CloseLibrary(DiskfontBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "diskfont.library(36)";
hnum = H_Library;
}
CloseLibrary(IconBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "icon.library(37)";
hnum = H_Library;
}
CloseLibrary(UtilityBase);
}
if (!e) {
e = "Unable to Open %s";
e1= "utility.library(37)";
hnum = H_Library;
}
CloseLibrary(AslBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "asl.library(37)";
hnum = H_Library;
}
CloseLibrary(GadToolsBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "gadtools.library(37)";
hnum = H_Library;
}
CloseLibrary(LayersBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "layers.library(37)";
hnum = H_Library;
}
CloseLibrary(GfxBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "graphics.library(37)";
hnum = H_Library;
}
CloseLibrary(IFFParseBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "iffparse.library(37)";
hnum = H_Library;
}
CloseLibrary(RexxSysBase);
}
if (!e) {
e = "Unable to Open %s";
e1 = "rexxsyslib.library(0)";
hnum = H_Library;
}
// Display an error message
if (e != (char *)-1) {
Error(e,"Quit",e1,hnum);
}
}
if (OpalBase) {
CloseLibrary((struct Library *)OpalBase);
}
if (TimerBase) {
CloseDevice((struct IORequest *) &tr);
}
if (AmigaGuideBase) {
if (handle) {
CloseAmigaGuide(handle);
}
CloseLibrary(AmigaGuideBase);
}
if (DCTVBase) {
CloseLibrary(DCTVBase);
}
if (ReqToolsBase) {
CloseLibrary(ReqToolsBase);
}
}
// save an image
BOOL
SaveFile(void) {
struct ILBMInfo *ilbm; // IFF stuff to save
BPTR fh; // File handle for PPM
BOOL OkFlag = TRUE;
struct BitMap TBM; // Temp bit map
struct DiskObject *MyDiskObject; // The Icon
char *iconname; // iconname
char *iconname1; // alternate iconname
if (!PPM) {
// Not PPM
if (OVFormat) {
// OpalVision so convert RGB to OpalVision
RGBtoOV(OScrn,p,0,0,swidth,height);
}
else {
// Set up BitMap
InitBitMap(&MyBitMap,(DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:24)))),width,height);
InitRastPort(&RP);
RP.BitMap = &MyBitMap;
InitRastPort(&TRP);
InitBitMap(&TBM,(DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:8)))),width,1);
TBM.BytesPerRow = (((width+15)>>4)<<1);
TBM.Rows = 1;
TRP.BitMap = &TBM;
TBM.Planes[0]=plane0;
TBM.Planes[1]=plane1;
TBM.Planes[2]=plane2;
TBM.Planes[3]=plane3;
TBM.Planes[4]=plane4;
TBM.Planes[5]=plane5;
TBM.Planes[6]=plane6;
TBM.Planes[7]=plane7;
if (!HAM6 && !HAM8 && !BW16 && !BW256 && !DCTV3 && !DCTV4) {
// i.e. 24 bit ILBM?
// so convert chunky to planar
MyBitMap.BitMap.Depth = 8;
MyBitMap.BitMap.Planes[0] = Planes[0];
MyBitMap.BitMap.Planes[1] = Planes[1];
MyBitMap.BitMap.Planes[2] = Planes[2];
MyBitMap.BitMap.Planes[3] = Planes[3];
MyBitMap.BitMap.Planes[4] = Planes[4];
MyBitMap.BitMap.Planes[5] = Planes[5];
MyBitMap.BitMap.Planes[6] = Planes[6];
MyBitMap.BitMap.Planes[7] = Planes[7];
WritePixelArray8(&RP,0,0,width-1,height-1,RED,&TRP);
WaitBlit();
MyBitMap.BitMap.Planes[0] = Planes[8];
MyBitMap.BitMap.Planes[1] = Planes[9];
MyBitMap.BitMap.Planes[2] = Planes[10];
MyBitMap.BitMap.Planes[3] = Planes[11];
MyBitMap.BitMap.Planes[4] = Planes[12];
MyBitMap.BitMap.Planes[5] = Planes[13];
MyBitMap.BitMap.Planes[6] = Planes[14];
MyBitMap.BitMap.Planes[7] = Planes[15];
WritePixelArray8(&RP,0,0,width-1,height-1,GREEN,&TRP);
WaitBlit();
MyBitMap.BitMap.Planes[0] = Planes[16];
MyBitMap.BitMap.Planes[1] = Planes[17];
MyBitMap.BitMap.Planes[2] = Planes[18];
MyBitMap.BitMap.Planes[3] = Planes[19];
MyBitMap.BitMap.Planes[4] = Planes[20];
MyBitMap.BitMap.Planes[5] = Planes[21];
MyBitMap.BitMap.Planes[6] = Planes[22];
MyBitMap.BitMap.Planes[7] = Planes[23];
WritePixelArray8(&RP,0,0,width-1,height-1,BLUE,&TRP);
WaitBlit();
}
// Reset up BitMap
MyBitMap.BitMap.Depth = (DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:24))));
MyBitMap.BitMap.Planes[0] = Planes[0];
MyBitMap.BitMap.Planes[1] = Planes[1];
MyBitMap.BitMap.Planes[2] = Planes[2];
MyBitMap.BitMap.Planes[3] = Planes[3];
MyBitMap.BitMap.Planes[4] = Planes[4];
MyBitMap.BitMap.Planes[5] = Planes[5];
MyBitMap.BitMap.Planes[6] = Planes[6];
MyBitMap.BitMap.Planes[7] = Planes[7];
MyBitMap.BitMap.Planes[8] = Planes[8];
MyBitMap.BitMap.Planes[9] = Planes[9];
MyBitMap.BitMap.Planes[10] = Planes[10];
MyBitMap.BitMap.Planes[11] = Planes[11];
MyBitMap.BitMap.Planes[12] = Planes[12];
MyBitMap.BitMap.Planes[13] = Planes[13];
MyBitMap.BitMap.Planes[14] = Planes[14];
MyBitMap.BitMap.Planes[15] = Planes[15];
MyBitMap.BitMap.Planes[16] = Planes[16];
MyBitMap.BitMap.Planes[17] = Planes[17];
MyBitMap.BitMap.Planes[18] = Planes[18];
MyBitMap.BitMap.Planes[19] = Planes[19];
MyBitMap.BitMap.Planes[20] = Planes[20];
MyBitMap.BitMap.Planes[21] = Planes[21];
MyBitMap.BitMap.Planes[22] = Planes[22];
MyBitMap.BitMap.Planes[23] = Planes[23];
}
}
// Set up output file name
sprintf(FileName,AnimName,f+Start-1);
if (PPM) {
// PPM Save is very simple P6 mode
AddMessage("Saving PPM image");
if (fh = Open(FileName,MODE_NEWFILE)) {
sprintf(buffer,"P6\n%ld %ld\n255\n",width,height);
FPuts(fh,buffer);
arrayr=RED;
arrayg=GREEN;
arrayb=BLUE;
// loop thru lines
for (y=0;
(y<height) && OkFlag;
y++) {
// Loop thru columns
for (x=0;
x < width;
x++) {
FPutC(fh,*arrayr);
FPutC(fh,*arrayg);
FPutC(fh,*arrayb);
arrayr++;
arrayg++;
arrayb++;
}
// skip part word at end of line
arrayr += (swidth - width);
arrayg += (swidth - width);
arrayb += (swidth - width);
}
if (!Close(fh)) {
OkFlag = FALSE;
}
}
else {
OkFlag = FALSE;
}
}
else {
// Save non PPM
if (OVFormat) {
// Save OpalVision
if (!strcmp(OVFormat,"JPG")) {
AddMessage("Saving Opal JPEG image");
// Save JPEG
OkFlag = !SaveJPEG24(OScrn,FileName,(OVThumb?0:NOTHUMBNAIL),OVQuality);
}
else {
AddMessage("Saving Opal IFF24 image");
// Save IFF
OkFlag = !SaveIFF24(OScrn,FileName,NULL,(OVThumb?0:NOTHUMBNAIL)|(OVFast?OVFASTFORMAT:0));
}
}
else {
if (HAM6) {
AddMessage("Saving HAM6 image");
OkFlag = SaveHAM6(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (HAM8) {
AddMessage("Saving HAM8 image");
OkFlag = SaveHAM8(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (BW16) {
AddMessage("Saving BW16 image");
OkFlag = SaveBW16(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (BW256) {
AddMessage("Saving BW256 image");
OkFlag = SaveBW256(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
if (DCTV3 || DCTV4) {
AddMessage(DCTV3?"Saving DCTV3 image":"Saving DCTV4 image");
OkFlag = SaveDCTV(FileName,width,height,swidth,
pwidth,pheight,pmode,
RED,GREEN,BLUE,&RP,&TRP);
}
else {
AddMessage("Saving ILBM24 image");
// allocate some IFF stuff
if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
if (ilbm->ParseInfo.iff = AllocIFF()) {
OkFlag = !saveilbm(ilbm, &MyBitMap, pmode,
width, height, pwidth, pheight,
NULL, 0, 0, /* colortable */
mskNone, 0, /* masking, transparent */
NULL, NULL, /* chunklists */
FileName);
// Close everything down cleanly
FreeIFF(ilbm->ParseInfo.iff);
}
else {
OkFlag = FALSE;
}
FreeMem(ilbm,sizeof(struct ILBMInfo));
}
else {
OkFlag = FALSE;
}
}
}
}
}
}
}
}
if (OkFlag) {
if (CreateIcons) {
// try to save an Icon
if (MyDiskObject = GetDiskObject(FileName)) {
// Do not overwrite if already present
FreeDiskObject(MyDiskObject);
}
else {
// Set up two possible names
if (OVFormat) {
if (!strcmp(OVFormat,"JPG")) {
iconname = "ENV:TSMorph/def_jpg";
iconname1 = "ENV:SYS/def_jpg";
}
else {
iconname = "ENV:TSMorph/def_iff";
iconname1 = "ENV:SYS/def_iff";
}
}
else {
if (PPM) {
iconname = "ENV:TSMorph/def_ppm";
iconname1 = "ENV:SYS/def_ppm";
}
else {
if (BW16) {
iconname = "ENV:TSMorph/def_bw16";
iconname1 = "ENV:SYS/def_bw16";
}
else {
if (BW256) {
iconname = "ENV:TSMorph/def_bw256";
iconname1 = "ENV:SYS/def_bw256";
}
else {
if (HAM6) {
iconname = "ENV:TSMorph/def_ham6";
iconname1 = "ENV:SYS/def_ham6";
}
else {
if (HAM8) {
iconname = "ENV:TSMorph/def_ham8";
iconname1 = "ENV:SYS/def_ham8";
}
else {
if (DCTV3) {
iconname = "ENV:TSMorph/def_dctv3";
iconname1 = "ENV:SYS/def_dctv3";
}
else {
if (DCTV4) {
iconname = "ENV:TSMorph/def_dctv4";
iconname1 = "ENV:SYS/def_dctv4";
}
else {
iconname = "ENV:TSMorph/def_ilbm";
iconname1 = "ENV:SYS/def_ilbm";
}
}
}
}
}
}
}
}
// Try two names, as last resort use default project
if ((MyDiskObject = GetDiskObject(iconname)) ||
(MyDiskObject = GetDiskObject(iconname1)) ||
(MyDiskObject = GetDefDiskObject(WBPROJECT))) {
PutDiskObject(FileName,MyDiskObject);
FreeDiskObject(MyDiskObject);
}
}
}
}
if (!OkFlag) {
Error("Error saving file '%s'","Quit",FileName,H_ESave);
}
else {
// Post image processing
if (strcmp(Postscript,"OFF")) {
strcpy(buffer,Postscript);
strcat(buffer," %ld %ld %ld %s");
sprintf(buffer1,buffer,f+Start-1,Frames,Single,FileName);
AddMessage("Postscript processing");
OkFlag = !SendRxMsg(buffer1,FALSE);
}
}
return OkFlag;
}
extern UWORD FileFormat = 0;
/* recognized file formats */
#define FORMAT_IFF 1
#define FORMAT_JPEG 2
#define FORMAT_GIF 3
#define FORMAT_PPM 4
#define FORMAT_TARGA 5
/* Opens a 24 bit image
* filename = name of file
* pic = structure to update
* GUI = TRUE to display error message
* Returns TRUE if ok
*/
BOOL
Load24bit(char *filename,struct Picture *pic,BOOL GUI) {
char *e = NULL; // Error message main text
char *e1 = NULL; // sub text,
struct RastPort RP, // Rastport
TRP; // Temp rastport
struct BitMap BM, // Bitmap
TBM; // Temp bitmap
ULONG hnum = 0; // Help on error
BOOL OkFlag=TRUE; // Still OK?
char buffer[256], // For Rexx Scripts
buffer1[256];
long Err; // Opal error
BPTR fh;
UBYTE zbuffer[5]="\0\0\0\0";
decompress_info_ptr info; // Load JPEG stuff
UWORD i,j;
LONG penno;
struct RastPort Rp; // Rast port for conversion
UBYTE *rx,*gx,*bx;
UBYTE rr,gg,bb;
UWORD EHB;
BOOL isHAM6 = FALSE;
BOOL isHAM8 = FALSE;
BOOL isEHB = FALSE;
struct DisplayInfo queryinfo;
DisplayInfoHandle dhandle = NULL;
struct DCTVCvtHandle *chandle=NULL; // DCTV conversion stuff
UWORD *DCTVcolors=NULL; // DCTV palette
if (filename) {
// Load image processing
if (strcmp(Loadscript,"OFF")) {
strcpy(buffer,Loadscript);
strcat(buffer," %ld %ld %ld %ld %s");
sprintf(buffer1,buffer,f+Start-1,Frames,Single,(pic==&Pic1)?0:1,filename);
AddMessage("Loadscript processing");
OkFlag = !SendRxMsg(buffer1,FALSE);
if (!OkFlag) {
e = (char *)-1;
GUI = FALSE; // Do not display error
}
}
pic->rgbonelot = FALSE;
if (!e) {
// determine file format
if (fh = Open(filename,MODE_OLDFILE)) {
FRead(fh,zbuffer,4,1);
if ((!strcmp(zbuffer,"FORM")) ||
(!strcmp(zbuffer,"CAT ")) ||
(!strcmp(zbuffer,"LIST"))) {
FileFormat = FORMAT_IFF;
}
else {
if ((zbuffer[0] == 0xFF) &&
(zbuffer[1] == 0xD8)) {
FileFormat = FORMAT_JPEG;
}
else {
if ((zbuffer[0] == 'G') &&
(zbuffer[1] == 'I') &&
(zbuffer[2] == 'F')) {
FileFormat = FORMAT_GIF;
}
else {
if ((zbuffer[0] == 'P') &&
((zbuffer[1] == '2') ||
(zbuffer[1] == '3') ||
(zbuffer[1] == '5') ||
(zbuffer[1] == '6'))) {
FileFormat = FORMAT_PPM;
}
else {
FileFormat = FORMAT_TARGA;
}
}
}
}
Close(fh);
}
else {
e = "Error opening file '%s'";
e1 = filename;
hnum = H_Open;
OkFlag = FALSE;
}
}
if (OkFlag) {
AddMessage((pic == &Pic2)?"Loading image 2":"Loading image 1");
}
// We have a file name
if (OkFlag && (FileFormat != FORMAT_IFF)) {
// Not an IFF file so use JPEG code
AddMessage((FileFormat == FORMAT_JPEG)?"Loading JFIF":
(FileFormat == FORMAT_GIF)?"Loading GIF":
(FileFormat == FORMAT_PPM)?"Loading PPM":
(FileFormat == FORMAT_TARGA)?"Loading Targa?":
"Loading ?");
if ((info = LoadJPEG(filename,0,NULL,NULL,NULL,NULL)) &&
(info->output_file)) {
AddMessage("Allocating work memory");
pic->rgbonelot = TRUE;
pic->red = (UBYTE *)info->output_file;
pic->green = pic->red + (((info->image_width+15)>>4)<<4) * info->image_height;
pic->blue = pic->green + (((info->image_width+15)>>4)<<4) * info->image_height;
// Allocate temp bit maps if first image and no OpalVision save
if ((OVFormat) || (plane0) ||
((plane0 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane1 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane2 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane3 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane4 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane5 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane6 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane7 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)))) {
return TRUE;
}
else {
e = "Unable to %s";
e1 = "allocate memory for bitmap";
hnum = H_AllocPlanes;
}
}
}
if (OkFlag && (FileFormat == FORMAT_IFF)) {
// Load iff
AddMessage("Loading IFF");
if (pic->ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
// IFF stuff
if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
// more iff stuff
pic->ilbm->ParseInfo.propchks = props;
pic->ilbm->ParseInfo.collectchks = nowt;
pic->ilbm->ParseInfo.stopchks = stops;
// Load the image using IFF routines
if (!(loadbrush(pic->ilbm,filename))) {
// Close the file and validate
closeifile(&(pic->ilbm->ParseInfo));
pwidth = width < 320 ? 320 : width;
pheight = height < 200 ? 200 : height;
pmode = pwidth >= 640 ? HIRES : 0L;
pmode |= pheight >= 400 ? LACE : 0L;
// ?????? width = pic->ilbm->Bmhd.w;
// Allocate chunky bit maps
AddMessage("Allocating Bitmaps");
if ((pic->red = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
(pic->green = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
(pic->blue = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
// Allocate temp bit maps if first image and no OpalVision save
((OVFormat && (pic->ilbm->Bmhd.nPlanes != 24)) || (plane0) ||
((plane0 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane1 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane2 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane3 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane4 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane5 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane6 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane7 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP))))) {
if (pic->ilbm->Bmhd.nPlanes == 24) {
// Convert 24 bit planar to chunky
AddMessage("Converting 24 bit to Chunky");
// Initialise rast ports/bitmaps
InitRastPort(&RP);
InitRastPort(&TRP);
InitBitMap(&TBM,8,pic->ilbm->Bmhd.w,1);
TRP.BitMap = &TBM;
TBM.Planes[0]=plane0;
TBM.Planes[1]=plane1;
TBM.Planes[2]=plane2;
TBM.Planes[3]=plane3;
TBM.Planes[4]=plane4;
TBM.Planes[5]=plane5;
TBM.Planes[6]=plane6;
TBM.Planes[7]=plane7;
InitBitMap(&BM,8,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
RP.BitMap = &BM;
BM.Planes[0] = pic->ilbm->brbitmap->Planes[0];
BM.Planes[1] = pic->ilbm->brbitmap->Planes[1];
BM.Planes[2] = pic->ilbm->brbitmap->Planes[2];
BM.Planes[3] = pic->ilbm->brbitmap->Planes[3];
BM.Planes[4] = pic->ilbm->brbitmap->Planes[4];
BM.Planes[5] = pic->ilbm->brbitmap->Planes[5];
BM.Planes[6] = pic->ilbm->brbitmap->Planes[6];
BM.Planes[7] = pic->ilbm->brbitmap->Planes[7];
// Convert red to chunky
ReadPixelArray8(&RP,0,0,pic->ilbm->Bmhd.w-1,pic->ilbm->Bmhd.h-1,pic->red,&TRP);
WaitBlit();
BM.Planes[0] = pic->ilbm->brbitmap->Planes[8];
BM.Planes[1] = pic->ilbm->brbitmap->Planes[9];
BM.Planes[2] = pic->ilbm->brbitmap->Planes[10];
BM.Planes[3] = pic->ilbm->brbitmap->Planes[11];
BM.Planes[4] = pic->ilbm->brbitmap->Planes[12];
BM.Planes[5] = pic->ilbm->brbitmap->Planes[13];
BM.Planes[6] = pic->ilbm->brbitmap->Planes[14];
BM.Planes[7] = pic->ilbm->brbitmap->Planes[15];
// and green
ReadPixelArray8(&RP,0,0,pic->ilbm->Bmhd.w-1,pic->ilbm->Bmhd.h-1,pic->green,&TRP);
WaitBlit();
BM.Planes[0] = pic->ilbm->brbitmap->Planes[16];
BM.Planes[1] = pic->ilbm->brbitmap->Planes[17];
BM.Planes[2] = pic->ilbm->brbitmap->Planes[18];
BM.Planes[3] = pic->ilbm->brbitmap->Planes[19];
BM.Planes[4] = pic->ilbm->brbitmap->Planes[20];
BM.Planes[5] = pic->ilbm->brbitmap->Planes[21];
BM.Planes[6] = pic->ilbm->brbitmap->Planes[22];
BM.Planes[7] = pic->ilbm->brbitmap->Planes[23];
// and blue
ReadPixelArray8(&RP,0,0,pic->ilbm->Bmhd.w-1,pic->ilbm->Bmhd.h-1,pic->blue,&TRP);
WaitBlit();
AddMessage("Cleaning up");
// Set up stuff to write image
// ???? width = pic->ilbm->Bmhd.w;
// ???? height = pic->ilbm->Bmhd.h;
// Unload everything and exit cleanly
unloadbrush(pic->ilbm);
FreeIFF(pic->ilbm->ParseInfo.iff);
FreeMem(pic->ilbm,sizeof(struct ILBMInfo));
return TRUE;
}
else {
if (DCTVBase && TestDCTVSignature(pic->ilbm->brbitmap)) {
// Convert DCTV to chunky
if (DCTVcolors = AllocVec(2L<<pic->ilbm->Bmhd.nPlanes,NULL)) {
for (i=0; i < (1L<<pic->ilbm->Bmhd.nPlanes); ++i) {
DCTVcolors[i] = ((pic->ilbm->RGB[i*4+1] & 0xf0) << 4) |
((pic->ilbm->RGB[i*4+2] & 0xf0)) |
((pic->ilbm->RGB[i*4+3] & 0xf0) >> 4);
}
AddMessage("Converting DCTV to Chunky");
if (chandle = AllocDCTVCvtTags(pic->ilbm->brbitmap,
DCTVCVTA_Type, DCTVCVTT_DCTVtoRGB,
DCTVCVTA_Width, (((pic->ilbm->Bmhd.w+15)>>4)<<4),
DCTVCVTA_Height, pic->ilbm->Bmhd.h,
DCTVCVTA_Flags, ((pic->ilbm->camg & LACE)?DCTVCVTF_Lace:0)|
DCTVCVTF_CustomRGBBuf,
DCTVCVTA_ColorTable, DCTVcolors,
TAG_END)) {
chandle->Red = pic->red;
chandle->Green = pic->green;
chandle->Blue = pic->blue;
while (chandle->DstLineNum < chandle->Height) {
CvtDCTVLine(chandle);
if ((chandle->DstLineNum > 0) &&
(chandle->DstLineNum <= chandle->Height)) {
chandle->Red += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
chandle->Green += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
chandle->Blue += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
}
}
FreeVec(DCTVcolors);
FreeDCTVCvt(chandle);
// Unload everything and exit cleanly
unloadbrush(pic->ilbm);
FreeIFF(pic->ilbm->ParseInfo.iff);
FreeMem(pic->ilbm,sizeof(struct ILBMInfo));
return TRUE;
}
FreeVec(DCTVcolors);
}
}
else {
// determine special IFF mode
if ((dhandle = FindDisplayInfo(pic->ilbm->camg)) &&
(GetDisplayInfoData(dhandle,(UBYTE *)&queryinfo,sizeof(queryinfo),DTAG_DISP,NULL))) {
if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
AddMessage("Converting HAM6 to Chunky");
isHAM6 = TRUE;
}
else {
if ((pic->ilbm->Bmhd.nPlanes == 8) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
isHAM8 = TRUE;
AddMessage("Converting HAM8 to Chunky");
}
else {
if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE)) {
isEHB = TRUE;
AddMessage("Converting EHB to Chunky");
}
else {
AddMessage("Converting ILBM to Chunky");
}
}
}
}
// Convert to chunky
InitRastPort(&Rp);
Rp.BitMap = pic->ilbm->brbitmap;
rx = pic->red;
gx = pic->green;
bx = pic->blue;
// For each line
for (j = 0;
j < height;
++j) {
// Convert each column
// Note: this is very ineffecient in that it uses
// ReadPixel().
// But the cost is fairly small compared to the render time
if (isHAM6) {
rr = gg = bb = 0;
for (i = 0;
i < width;
++i) {
penno = ReadPixel(&Rp,i,j);
switch (penno & 0x30) {
case 0:
*rx++ = rr = pic->ilbm->RGB[penno*4+1];
*gx++ = gg = pic->ilbm->RGB[penno*4+2];
*bx++ = bb = pic->ilbm->RGB[penno*4+3];
break;
case 0x10:
*rx++ = rr;
*gx++ = gg;
*bx++ = bb = (penno&0xf)|((penno&0xf)<<4);
break;
case 0x20:
*rx++ = rr = (penno&0xf)|((penno&0xf)<<4);
*gx++ = gg;
*bx++ = bb;
break;
case 0x30:
*rx++ = rr;
*gx++ = gg = (penno&0xf)|((penno&0xf)<<4);
*bx++ = bb;
break;
}
}
}
else {
if (isHAM8) {
rr = gg = bb = 0;
for (i = 0;
i < width;
++i) {
penno = ReadPixel(&Rp,i,j);
switch (penno & 0xc0) {
case 0:
*rx++ = rr = pic->ilbm->RGB[penno*4+1];
*gx++ = gg = pic->ilbm->RGB[penno*4+2];
*bx++ = bb = pic->ilbm->RGB[penno*4+3];
break;
case 0x40:
*rx++ = rr;
*gx++ = gg;
*bx++ = bb = (penno&0x3f)<<2;
break;
case 0x80:
*rx++ = rr = (penno&0x3f)<<2;
*gx++ = gg;
*bx++ = bb;
break;
case 0xc0:
*rx++ = rr;
*gx++ = gg = (penno&0x3f)<<2;
*bx++ = bb;
break;
}
}
}
else {
if (isEHB) {
for (i = 0;
i < width;
++i) {
penno = ReadPixel(&Rp,i,j);
EHB = (penno & 0x20)?1:0;
penno &= 0x1f;
*rx++ = pic->ilbm->RGB[penno*4+1]>>EHB;
*gx++ = pic->ilbm->RGB[penno*4+2]>>EHB;
*bx++ = pic->ilbm->RGB[penno*4+3]>>EHB;
}
}
else {
for (i = 0;
i < width;
++i) {
penno = ReadPixel(&Rp,i,j);
*rx++ = pic->ilbm->RGB[penno*4+1];
*gx++ = pic->ilbm->RGB[penno*4+2];
*bx++ = pic->ilbm->RGB[penno*4+3];
}
}
}
}
rx += ((((width+15)>>4)<<4)-width);
gx += ((((width+15)>>4)<<4)-width);
bx += ((((width+15)>>4)<<4)-width);
}
AddMessage("Cleaning up");
unloadbrush(pic->ilbm);
FreeIFF(pic->ilbm->ParseInfo.iff);
FreeMem(pic->ilbm,sizeof(struct ILBMInfo));
return TRUE;
}
}
}
if (!e) {
e = "Unable to %s";
e1 = "allocate memory for bitmap";
hnum = H_AllocPlanes;
}
}
if (!e) {
e = "Error loading '%s'";
e1 = filename;
hnum = H_Load;
}
unloadbrush(pic->ilbm);
FreeIFF(pic->ilbm->ParseInfo.iff);
}
if (!e) {
e = "Unable to %s";
e1 = "AllocIFF";
hnum = H_AllocIFF;
}
FreeMem(pic->ilbm,sizeof(struct ILBMInfo));
}
if (!e) {
e = "Unable to '%s'";
e1 = "AllocMem for ILBMInfo";
hnum = H_AllocILBM;
}
}
if (OkFlag && OpalBase) {
// If we still have not loaded the image then try opal.library as a last resort
AddMessage("Loading using opal.library");
Err = LoadImage24(NULL,filename,VIRTUALSCREEN24|FORCE24);
if (Err < OL_ERR_MAXERR) {
switch (Err) {
case OL_ERR_OUTOFMEM:
e = "Failure - Out of memory - loading '%s'";
break;
case OL_ERR_OPENFILE:
e = "Failure - Opening file - loading '%s'";
break;
case OL_ERR_FORMATUNKNOWN:
e = "Failure - Unknown Format - loading '%s'";
break;
case OL_ERR_NOTILBM:
e = "Failure - Not an ILBM file - loading '%s'";
break;
case OL_ERR_FILEREAD:
e = "Failure - Reading file - loading '%s'";
break;
case OL_ERR_BADIFF:
e = "Failure - Bad IFF Format - loading '%s'";
break;
case OL_ERR_CANTCLOSE:
e = "Failure - Can not Close - loading '%s'";
break;
case OL_ERR_BADJPEG:
e = "Failure - Bad JPEG Format - loading '%s'";
break;
case OL_ERR_UNSUPPORTED:
e = "Failure - Unsupported Format - loading '%s'";
break;
case OL_ERR_CTRLC:
case OL_ERR_NOTHUMBNAIL:
case OL_ERR_OPENSCREEN:
case OL_ERR_FILEWRITE:
default:
e = "Failure - Unknown problem - loading '%s'";
break;
}
e1 = filename;
hnum = HE_OpalVision;
}
else {
AddMessage("Allocating Bitmaps");
pic->OScrn = (struct OpalScreen *)Err;
// Allocate chunky bit maps
if ((pic->red = AllocVec(((((pic->OScrn->Width+15)>>4)<<4)*pic->OScrn->Height),0)) &&
(pic->green = AllocVec(((((pic->OScrn->Width+15)>>4)<<4)*pic->OScrn->Height),0)) &&
(pic->blue = AllocVec(((((pic->OScrn->Width+15)>>4)<<4)*pic->OScrn->Height),0)) &&
// Allocate temp bit maps if first image and no OpalVision save
((OVFormat) || (plane0) ||
((plane0 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane1 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane2 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane3 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane4 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane5 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane6 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP)) &&
(plane7 = AllocVec((((width+15)>>4)<<4),MEMF_CHIP))))) {
AddMessage("Converting Opal to Chunky");
OVtoRGB(pic->OScrn,&(pic->red),0,0,((pic->OScrn->Width+15)>>4)<<4,pic->OScrn->Height);
}
else {
e = "Unable to %s";
e1 = "allocate memory for bitmap";
hnum = H_AllocPlanes;
}
FreeScreen24(pic->OScrn);
if (!e) {
return TRUE;
}
}
}
else {
if (!e) {
e = "No opal.library";
hnum = HE_NoOpal;
}
}
}
Close24bit(pic);
// Display an error message if required
if (GUI)
Error(e,"Quit",e1,hnum);
return(FALSE);
}
/* Close an image clearing everything down */
void
Close24bit(struct Picture *pic) {
if (pic) {
if (pic->rgbonelot) {
if (pic->red) {
FreeVec(pic->red);
}
pic->red = NULL;
pic->green = NULL;
pic->blue = NULL;
}
else {
if (pic->red) {
FreeVec(pic->red);
pic->red = NULL;
}
if (pic->green) {
FreeVec(pic->green);
pic->green = NULL;
}
if (pic->blue) {
FreeVec(pic->blue);
pic->blue = NULL;
}
}
}
}
/* Display an error message
* ErrorMessage : The main text
* Gadget : Text for one gadget
* extra : more of the text
* helpnum : Number of a help node
*
* See the TSMorph source code for more of how this actually works
*/
void
Error(char *ErrorMessage,char *Gadget,char *extra,ULONG helpnum) {
struct EasyStruct EasyStruct = {
sizeof(struct EasyStruct),
0,
NULL,
NULL,
NULL
};
UBYTE *title = "TSMorph-render Error";
struct Window *req;
UBYTE gad[32] = "Help|";
UBYTE gad1[32] = "_Help|_";
ULONG ret = CALL_HANDLER;
struct AmigaGuideMsg *agm;
ULONG signals;
struct rtHandlerInfo *rth;
// Disable the window and display the requester
DisableWindow();
if (ReqToolsBase) {
if (!handle) {
strcpy(gad1,"_");
}
strcat(gad1,Gadget);
while (ret) {
ret = CALL_HANDLER;
if (rtEZRequestTags(ErrorMessage,gad1,NULL,&extra,
RT_ReqHandler, &rth,
RT_Window, ProgressWnd,
RT_Underscore, '_',
RTEZ_ReqTitle, title,
TAG_END) == CALL_HANDLER) {
while (ret == CALL_HANDLER) {
if (!rth->DoNotWait) {
signals = Wait(rth->WaitMask | ASig);
}
ret = rtReqHandlerA(rth,signals,NULL);
if (ret == 1) {
help(helpnum);
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
}
else {
ret = 0;
}
}
}
else {
EasyStruct.es_TextFormat = ErrorMessage;
EasyStruct.es_Title = title;
if (handle) {
strcat(gad,Gadget);
}
else {
strcpy(gad,Gadget);
}
EasyStruct.es_GadgetFormat = gad;
req = BuildEasyRequest(ProgressWnd,&EasyStruct,NULL,extra);
while (ret) {
signals = Wait((1L << req->UserPort->mp_SigBit) | ASig);
if (signals & (1L << req->UserPort->mp_SigBit)) {
ret = SysReqHandler(req,NULL,FALSE);
if (ret == 1) {
help(helpnum);
}
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
FreeSysRequest(req);
}
EnableWindow();
}
/* Open a file
* Returns : TRUE if ok
* filename : name of file, or NULL for requester
*/
BOOL
MyOpen(char *filename,BOOL JustPoints) {
char dirname[257];
char *ifilename=NULL;
BOOL ok=TRUE;
BPTR fh;
char buffer[257];
LONG w,h;
LONG xx,x1,yy,y1;
struct FileRequester *filereq; // For file requester
struct MyPoint *MyPoint;
// If filename supplied then use it otherwise use file requester
if (filename) {
ifilename = filename;
}
else {
if (filereq = (struct FileRequest *)AllocFileRequest()) {
if (AslRequestTags((APTR) filereq,ASL_Hail,(Tag) "TSMorph-render - Pick project",TAG_DONE)) {
strncpy(dirname,filereq->rf_Dir,256);
if (AddPart(dirname,filereq->rf_File,256)) {
ifilename=dirname;
}
}
FreeFileRequest(filereq);
}
}
// If user did not cancel
if (ifilename) {
OpenNewArgs(ifilename); // Load new parameters
// Open file and skip the WB displayable names
if (fh=Open(ifilename,MODE_OLDFILE)) {
FGets(fh,buffer,256);
if (JustPoints && strcmp(buffer,"TSMorph 2.0\n")) {
Error("Invalid file format\nLine '%s'","Quit",buffer,H_FileFormat);
ok = FALSE;
}
else {
if (!JustPoints) {
Pic1.filename[0]=0;
Pic2.filename[0]=0;
// Keep file name
strcpy(MyFileName,ifilename);
strcat(MyFileName,".%03ld");
if (strcmp(buffer,"TSMorph 1.2\n")) {
Error("Assuming version 1.0 file format","OK",NULL,HE_OldFormat);
}
else {
FGets(fh,buffer,256);
}
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
strcpy(Pic1.filename,buffer);
FGets(fh,buffer,256);
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
strcpy(Pic2.filename,buffer);
// Get file name, set progress and try and load image
FGets(fh,buffer,256);
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
if (buffer[0]) {
strcpy(Pic1.filename,buffer);
}
FGets(fh,buffer,256);
if (strlen(buffer)) {
buffer[strlen(buffer)-1]=0;
}
if (buffer[0]) {
strcpy(Pic2.filename,buffer);
}
// Loaded both so get anim name
FGets(fh,AnimName,256);
if (strlen(AnimName)) {
AnimName[strlen(AnimName)-1]=0;
}
// Read and validate general information
FGets(fh,buffer,256);
if (ok && (sscanf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld",&w,&h,&Frames,&Single,&Start) != 5)) {
Error("Invalid file format\nLine '%s'","Quit",buffer,H_FileFormat);
}
else {
width = w; // ???????
height = h; // ???????
if (ok &&
((w != width) ||
(h != height))) {
Error("Size does not match image\nLine '%s'","Quit",buffer,H_SizeMatch);
ok = FALSE;
}
}
}
}
if (ok) {
PointCount = 0;
// Read and store all the points
while (ok &&
FGets(fh,buffer,256) &&
(sscanf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld",&xx,&yy,&x1,&y1) == 4)) {
if ((xx<0)||(xx>(width-1)) ||
(yy<0)||(yy>(height-1))) {
Error("Point out of range\nLine '%s'","Quit",buffer,H_Range);
ok = FALSE;
}
if (MyPoint = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
MyPoint->x = xx;
MyPoint->y = yy;
MyPoint->x1 = x1;
MyPoint->y1 = y1;
AddTail(&PointList,(struct Node *)MyPoint);
++PointCount;
}
else {
ok = FALSE;
}
}
}
if (ok) { // + 3 should actually be + 1 - but mungwall hits
if (Points = AllocVec((max(PointCount,23) + 3)*sizeof(struct MyPoint *),MEMF_CLEAR)) {
}
else {
Error("Out of memory for points","Quit",NULL,H_MemPointsR);
ok = FALSE;
}
}
// Close file and cleanup
if (!Close(fh)) {
if (ok) {
Error("Error closing file '%s'","Quit",filename,H_CloseFile);
ok = FALSE;
}
}
}
else {
Error("Error opening file '%s'","Quit",filename,H_Open);
ok = FALSE;
}
}
else {
ok = FALSE;
}
return ok;
}
/* Delete all the points from the list */
void
DeleteAllPoints(void) {
struct MyPoint *MyPoint;
// Loops looking at the head every time and deletes it
while ((MyPoint =(struct MyPoint *)PointList.lh_Head)->MyNode.mln_Succ) {
Remove((struct Node *)MyPoint);
FreeMem(MyPoint,sizeof(struct MyPoint));
}
if (Points) {
FreeVec(Points);
Points = NULL;
}
}
// The following is the alogrithm stuff!!!!!
// and is not particularly well commented!
/* Given a point, returns the coordinates in the first and last image */
void __regargs
FindPoint(struct MyPoint *RetPoint) {
UWORD KeepCount;
struct MyPoint *MyPoint,*MyPoint1,*MyPoint2;
struct MyPoint **p,**p1,**p2;
UWORD i1,i2;
UWORD i,j,k;
LONG checkdiff;
BOOL flag;
for (i = 0;
i < (Depth+3);
++i) {
Points[i] = &BigPoint;
}
// Set up differences
for (MyPoint = (struct MyPoint *)PointList.lh_Head;
MyPoint->MyNode.mln_Succ;
MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
if (x < MyPoint->Cx) {
MyPoint->xdiff = MyPoint->Cx - x;
}
else {
MyPoint->xdiff = x - MyPoint->Cx;
}
if (y < MyPoint->Cy) {
MyPoint->ydiff = MyPoint->Cy - y;
}
else {
MyPoint->ydiff = y - MyPoint->Cy;
}
if ((MyPoint->xdiff + MyPoint->ydiff) < Points[Depth+2]->Cdiff) {
MyPoint->Cdiff = MyPoint->xdiff * MyPoint->xdiff +
MyPoint->ydiff * MyPoint->ydiff;
flag = TRUE;
for (i = 0;
flag && (i < (Depth + 3));
++i) {
if (Points[i]->Cdiff > MyPoint->Cdiff) {
MyPoint1 = Points[i];
Points[i] = MyPoint;
for (j = i+1;
j < (Depth + 3);
++j) {
MyPoint2 = Points[j];
Points[j] = MyPoint1;
MyPoint1 = MyPoint2;
}
flag = FALSE;
}
}
}
}
// If on an actual point then easy
if (!Points[0]->Cdiff) {
if (AntiAlias) {
RetPoint->xd = Points[0]->x;
RetPoint->x1d = Points[0]->x1;
RetPoint->yd = Points[0]->y;
RetPoint->y1d = Points[0]->y1;
}
else {
RetPoint->x = Points[0]->x;
RetPoint->x1 = Points[0]->x1;
RetPoint->y = Points[0]->y;
RetPoint->y1 = Points[0]->y1;
}
return;
}
// otherwise try and find a triangle with the other points
KeepCount = 0;
if (Mode & MODE_CLOSEST) {
checkdiff = 0x7FFFFFFF;
for (p = Points, i=0;
i<(Depth+1);
++i,++p) {
if ((*p)->Cdiff < checkdiff) {
for (p1 = p+1, j=i;
j<(Depth+1);
++j,++p1) {
if (((*p)->Cdiff + (*p1)->Cdiff) < checkdiff) {
i1 = intersect(*p,*p1);
for (p2 = p1+1, k=j;
k<(Depth+1);
++k,++p2) {
// loop thru 3 point combinations finding smallest triangle
if (((*p)->Cdiff + (*p1)->Cdiff + (*p2)->Cdiff) < checkdiff) {
if (i1 + (i2 = intersect(*p1,*p2)) < 2) {
if ((i1 + i2 + intersect(*p2,*p)) == 1) {
KeepCount = 1;
MyPoint = *p;
MyPoint1 = *p1;
MyPoint2 = *p2;
checkdiff = (*p)->Cdiff + (*p1)->Cdiff + (*p2)->Cdiff;
}
}
}
}
}
}
}
}
}
else {
for (p = Points, i=0;
!KeepCount && (i<(Depth+1));
++i,++p) {
for (p1 = p+1, j=i;
!KeepCount && (j<(Depth+1));
++j,++p1) {
i1 = intersect(*p,*p1);
for (p2 = p1+1, k=j;
!KeepCount && (k<(Depth+1));
++k,++p2) {
// loop thru 3 point combinations finding smallest triangle
if (i1 + (i2 = intersect(*p1,*p2)) < 2) {
if ((i1 + i2 + intersect(*p2,*p)) == 1) {
MyPoint = *p;
MyPoint1 = *p1;
MyPoint2 = *p2;
KeepCount = 1;
}
}
}
}
}
}
// If still no triangle then assume stationary
if (!KeepCount && (Mode & MODE_STAT)) {
if (AntiAlias) {
RetPoint->xd = x;
RetPoint->x1d = x;
RetPoint->yd = y;
RetPoint->y1d = y;
}
else {
RetPoint->x = x;
RetPoint->y = y;
RetPoint->x1 = x;
RetPoint->y1 = y;
}
return;
}
if (!KeepCount) {
MyPoint = Points[0];
MyPoint1 = Points[1];
MyPoint2 = Points[2];
}
// Otherwise do the triangle calculation
Triangle(RetPoint,MyPoint,MyPoint1,MyPoint2);
// Check the point is actually on the image
if (AntiAlias) {
if (RetPoint->xd < 0) {
RetPoint->xd = 0;
}
if (RetPoint->yd < 0) {
RetPoint->yd = 0;
}
if (RetPoint->x1d < 0) {
RetPoint->x1d = 0;
}
if (RetPoint->y1d < 0) {
RetPoint->y1d = 0;
}
if (RetPoint->xd > (width-1)) {
RetPoint->xd = width-1;
}
if (RetPoint->yd > (height-1)) {
RetPoint->yd = height-1;
}
if (RetPoint->x1d > (width-1)) {
RetPoint->x1d = width-1;
}
if (RetPoint->y1d > (height-1)) {
RetPoint->y1d = height-1;
}
}
else {
if (RetPoint->x < 0) {
RetPoint->x = 0;
}
if (RetPoint->y < 0) {
RetPoint->y = 0;
}
if (RetPoint->x1 < 0) {
RetPoint->x1 = 0;
}
if (RetPoint->y1 < 0) {
RetPoint->y1 = 0;
}
if (RetPoint->x > (width-1)) {
RetPoint->x = width-1;
}
if (RetPoint->y > (height-1)) {
RetPoint->y = height-1;
}
if (RetPoint->x1 > (width-1)) {
RetPoint->x1 = width-1;
}
if (RetPoint->y1 > (height-1)) {
RetPoint->y1 = height-1;
}
}
}
/* Used to determine if a point lies on a line,
* or in triangle of 3 points
*/
UWORD __regargs
intersect(struct MyPoint *Pointa,struct MyPoint *Pointb) {
// Draws line between a and b and sees if line from x,0 to x,y intersects
// returns 1 if intersects, 0 if not intersect
if (Pointb->Cx == Pointa->Cx) { // Vertical a to b
if ((Pointb->x == x) && // x,y on a to b
(((Pointb->Cy > y) && (Pointa->Cy < y)) ||
((Pointb->Cy < y) && (Pointa->Cy > y)))) {
return 1; // Beteen a and b
}
return 0;
}
if (((Pointb->Cy > y) && (Pointa->Cy > y)) ||
((Pointb->Cx > x) && (Pointa->Cx > x)) ||
((Pointb->Cx < x) && (Pointa->Cx < x))) { // Can not possibly cross
return 0;
}
if ((Pointb->Cy < y) && (Pointa->Cy < y)) {
return 1;
}
if (Pointa->Cx == x) {
if (Pointa->Cy > y) {
return 0;
}
return 1;
}
if (Pointb->Cx == x) {
if (Pointb->Cy > y) {
return 0;
}
return 1;
}
if (Pointb->Cy == Pointa->Cy) {
if (Pointa->Cy > y) {
return 0;
}
return 1;
}
if ((((Pointa->Cx < x)?(x - Pointa->Cx):(Pointa->Cx - x)) * Pointb->Cy +
((Pointb->Cx < x)?(x - Pointb->Cx):(Pointb->Cx - x)) * Pointa->Cy) /
((Pointb->Cx < Pointa->Cx)?(Pointa->Cx - Pointb->Cx):(Pointb->Cx - Pointa->Cx)) > y) {
return 0;
}
return 1;
}
/* Given 3 points (a,b,c) with a point (p) in the triangle
* determine the coordinates of point (p) on the first and last frame
*/
void __regargs
Triangle(struct MyPoint *p,struct MyPoint *a,struct MyPoint *bb,struct MyPoint *c) {
double AB1,AB2,BC1,BC2,CA1,CA2;
double AB,BC,CA;
double ABBCCA2;
double ABCA,BCCA,ABBC;
double BC1BC2,AB1AB2,CA1CA2;
CalcDiffs(a,bb,&AB1,&AB2,&AB);
CalcDiffs(bb,c,&BC1,&BC2,&BC);
CalcDiffs(c,a,&CA1,&CA2,&CA);
ABBCCA2 = 2 * (AB + BC + CA);
ABCA = AB+CA;
BCCA = BC+CA;
ABBC = AB+BC;
BC1BC2 = BC1+BC2;
AB1AB2 = AB1+AB2;
CA1CA2 = CA1+CA2;
if (AntiAlias) {
p->xd = x +
(ABCA*(BC1*(c->x - c->Cx) + BC2*(bb->x - bb->Cx)) / BC1BC2 +
BCCA*(AB1*(bb->x - bb->Cx) + AB2*(a->x - a->Cx)) / AB1AB2 +
ABBC*(CA1*(a->x - a->Cx) + CA2*(c->x - c->Cx)) / CA1CA2) /
ABBCCA2;
p->x1d = x +
(ABCA*(BC1*(c->x1 - c->Cx) + BC2*(bb->x1 - bb->Cx)) / BC1BC2 +
BCCA*(AB1*(bb->x1 - bb->Cx) + AB2*(a->x1 - a->Cx)) / AB1AB2 +
ABBC*(CA1*(a->x1 - a->Cx) + CA2*(c->x1 - c->Cx)) / CA1CA2) /
ABBCCA2;
p->y1d = y +
(ABCA*(BC1*(c->y1 - c->Cy) + BC2*(bb->y1 - bb->Cy)) / BC1BC2 +
BCCA*(AB1*(bb->y1 - bb->Cy) + AB2*(a->y1 - a->Cy)) / AB1AB2 +
ABBC*(CA1*(a->y1 - a->Cy) + CA2*(c->y1 - c->Cy)) / CA1CA2) /
ABBCCA2;
p->yd = y +
(ABCA*(BC1*(c->y - c->Cy) + BC2*(bb->y - bb->Cy)) / BC1BC2 +
BCCA*(AB1*(bb->y - bb->Cy) + AB2*(a->y - a->Cy)) / AB1AB2 +
ABBC*(CA1*(a->y - a->Cy) + CA2*(c->y - c->Cy)) / CA1CA2) /
ABBCCA2;
}
else {
p->x = x +
(ABCA*(BC1*(c->x - c->Cx) + BC2*(bb->x - bb->Cx)) / BC1BC2 +
BCCA*(AB1*(bb->x - bb->Cx) + AB2*(a->x - a->Cx)) / AB1AB2 +
ABBC*(CA1*(a->x - a->Cx) + CA2*(c->x - c->Cx)) / CA1CA2) /
ABBCCA2;
p->x1 = x +
(ABCA*(BC1*(c->x1 - c->Cx) + BC2*(bb->x1 - bb->Cx)) / BC1BC2 +
BCCA*(AB1*(bb->x1 - bb->Cx) + AB2*(a->x1 - a->Cx)) / AB1AB2 +
ABBC*(CA1*(a->x1 - a->Cx) + CA2*(c->x1 - c->Cx)) / CA1CA2) /
ABBCCA2;
p->y1 = y +
(ABCA*(BC1*(c->y1 - c->Cy) + BC2*(bb->y1 - bb->Cy)) / BC1BC2 +
BCCA*(AB1*(bb->y1 - bb->Cy) + AB2*(a->y1 - a->Cy)) / AB1AB2 +
ABBC*(CA1*(a->y1 - a->Cy) + CA2*(c->y1 - c->Cy)) / CA1CA2) /
ABBCCA2;
p->y = y +
(ABCA*(BC1*(c->y - c->Cy) + BC2*(bb->y - bb->Cy)) / BC1BC2 +
BCCA*(AB1*(bb->y - bb->Cy) + AB2*(a->y - a->Cy)) / AB1AB2 +
ABBC*(CA1*(a->y - a->Cy) + CA2*(c->y - c->Cy)) / CA1CA2) /
ABBCCA2;
}
}
/* Caclulate the distances between various points */
void __regargs
CalcDiffs(struct MyPoint *a,struct MyPoint *bb,double *ab1,double *ab2,double *ab) {
// ab is length x,y to line ab
// ab1 is length x,y to intersect of ab
// ab2 is length intersect of ab to bb
double m;
double c; // y = mx+c line a to bb
double n;
double d; // y = nx+d line perp to y=mx+c thru x,y
double xsolve,ysolve;
if (a->Cx == bb->Cx) {
*ab = a->xdiff;
*ab1 = a->ydiff;
*ab2 = bb->ydiff;
}
else {
if (a->Cy == bb->Cy) {
*ab1 = a->xdiff;
*ab2 = bb->xdiff;
*ab = a->ydiff;
}
else {
m = (double)(bb->Cy - a->Cy) / (double)(bb->Cx - a->Cx);
c = bb->Cy - (bb->Cx * m);
n = (-1) / m;
d = y - n * x;
xsolve = (d - c)/(m - n);
ysolve = m * xsolve + c;
*ab1 = sqrt(((a->Cy - ysolve) * (a->Cy - ysolve) + (a->Cx - xsolve) * (a->Cx - xsolve)));
*ab2 = sqrt(((bb->Cy - ysolve) * (bb->Cy - ysolve) + (bb->Cx - xsolve) * (bb->Cx - xsolve)));
*ab = sqrt(((y - ysolve) * (y - ysolve) + (x - xsolve) * (x - xsolve)));
}
}
}
/* Frame clicked - irrelevant */
int
FrameClicked(void) {
return 1;
}
/* Line clicked - irrelevant */
int
LineClicked(void) {
return 1;
}
/* Routine for when Stop clicked */
int
StopClicked(void) {
struct EasyStruct EasyStruct = {
sizeof(struct EasyStruct),
0,
NULL,
NULL,
NULL,
};
UBYTE *title = "TSMorph-render";
UBYTE *body = "Really quit?";
struct Window *req;
UBYTE *gad;
ULONG ret = 2;
struct AmigaGuideMsg *agm;
ULONG signals;
struct rtHandlerInfo *rth;
// Disable the window, display a requester and reenable the window
DisableWindow();
if (ReqToolsBase) {
if (handle) {
gad = "_Quit|_Help|_Continue";
}
else {
gad = "_Quit|_Continue";
}
while (ret == 2) {
ret = CALL_HANDLER;
if (rtEZRequestTags(body,gad,NULL,NULL,
RT_ReqHandler, &rth,
RT_Window, ProgressWnd,
RT_Underscore, '_',
RTEZ_ReqTitle, title,
TAG_END) == CALL_HANDLER) {
while (ret == CALL_HANDLER) {
if (!rth->DoNotWait) {
signals = Wait(rth->WaitMask | ASig);
}
ret = rtReqHandlerA(rth,signals,NULL);
if (ret == 2) {
help(H_Really);
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
}
else {
ret = 0;
}
}
}
else {
EasyStruct.es_TextFormat = body;
EasyStruct.es_Title = title;
if (handle) {
EasyStruct.es_GadgetFormat = "Quit|Help|Continue";
}
else {
EasyStruct.es_GadgetFormat = "Quit|Continue";
}
req = BuildEasyRequest(ProgressWnd,&EasyStruct,NULL,NULL);
while ((ret = SysReqHandler(req,NULL,TRUE)) == 2) {
help(H_Really);
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
FreeSysRequest(req);
}
EnableWindow();
return !ret;
}
/* Disables the Progress window
* Disables the 'Stop' gadget and displays a wait pointer
*/
void
DisableWindow(void) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Stop],ProgressWnd,NULL,GA_Disabled,TRUE,TAG_END);
SetPointer(ProgressWnd, BusyPointerData, 16, 16, -6, 0);
}
}
/* Enables the Progress window
* Enables the 'Stop' gadget and clears the pointer
*/
void
EnableWindow(void) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Stop],ProgressWnd,NULL,GA_Disabled,FALSE,TAG_END);
ClearPointer(ProgressWnd);
}
}
/* Tries to execute a Rexx script
* msgtxt = name of script
* IgnoreError = TRUE then do not display error message
* Returns: error message
*/
LONG
SendRxMsg(char *msgtxt,BOOL IgnoreError) {
struct MsgPort *reply_port;
struct MsgPort *rx_port;
struct RexxMsg *rx_msg;
LONG ret = RC_FATAL;
if (reply_port = CreateMsgPort()) {
if (rx_msg = CreateRexxMsg(reply_port,"TSM","REXX")) {
rx_msg->rm_Args[0] = msgtxt;
if (FillRexxMsg(rx_msg,1,0)) {
rx_msg->rm_Action = RXCOMM;
Forbid();
if (rx_port = (struct MsgPort *)FindPort("REXX")) {
PutMsg(rx_port, (struct Message *)rx_msg);
Permit();
WaitPort(reply_port);
ReplyMsg(GetMsg(reply_port));
ret = rx_msg->rm_Result1;
}
else {
Permit();
}
ClearRexxMsg(rx_msg, 1);
}
DeleteRexxMsg(rx_msg);
}
DeleteMsgPort(reply_port);
}
// Display an error message (if required)
if (!IgnoreError && ret) {
Error("Error sending ARexx message\n'%s'","Quit",msgtxt,H_ARexx);
}
return ret;
}
/* Handle 'Help' key */
int
ProgressRawKey(void) {
switch (ProgressMsg.Code) {
case 0x5f:
help(H_Help);
}
return 1;
}
// Load some image(s) for a frame
BOOL
LoadFrames(BOOL points,BOOL image1,BOOL image2) {
char buffer[257];
BOOL ok=TRUE;
if ((Single == 2) || (Single == 3)) {
if (points) {
AddMessage("Loading points");
DeleteAllPoints();
sprintf(buffer,MyFileName,f+Start-1);
ok = MyOpen(buffer,TRUE);
}
sprintf(buffer,Pic1.filename,f+Start-1);
}
else {
strcpy(buffer,Pic1.filename);
}
if (ok) {
if (image1) {
ok = Pic1_Open = Load24bit(buffer,&Pic1,TRUE);
}
if (image2 && ok && ((Single == 0) || (Single == 2))) {
// If we loaded the 1st image then try the second
if (Single == 2) {
sprintf(buffer,Pic2.filename,f+Start-1);
}
else {
strcpy(buffer,Pic2.filename);
}
ok = Pic2_Open = Load24bit(buffer,&Pic2,TRUE);
}
}
return ok;
}
static UWORD top = 0;
// add a message to the progress list
void
AddMessage(UBYTE *message) {
struct Node *node;
if ((node = (struct Node *)malloc(sizeof(struct Node))) &&
(node->ln_Name = strdup(message))) {;
GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
GTLV_Labels, ~0,
TAG_END);
AddTail(&InfoList,node);
GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
GTLV_Labels, &InfoList,
GTLV_Top, top,
TAG_END);
top++;
}
}